﻿//
// (C) Copyright 2009 Irantha Suwandarathna (irantha@gmail.com)
// All rights reserved.
//

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using EffiProzDB;
using EffiProzDB.Lib;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace EffiProzDBTest
{
    public static class TestHelper
    {

        static int tableCounter = 0;

        public static string GetNewTableName()
        {
            lock (typeof(TestHelper))
            {
                return "Table" + tableCounter++;
            }
        }

        public static Result ExecuteUpdateSQL_Success(SessionInterface sessionProxy, string sql)
        {
            Result resultOut = new Result(ResultConstants.SQLEXECDIRECT);
            resultOut.setMainString(sql);
            resultOut.setMaxRows(1000);

            Result resultIn = sessionProxy.execute(resultOut);
            Assert.IsNotNull(resultIn, resultIn.getMainString());
            if(resultIn.isError())
                Assert.Fail( resultIn.getMainString() +" "+resultIn.getException().Message+" "+resultIn.getException().StackTrace);
            Assert.IsFalse(resultIn.isData(),resultIn.getMainString());

            return resultIn;
        }

        public static Result ExecutePrepareStatement(SessionInterface sessionProxy, string sql, object[] parameters)
        {
            Result resultOut = new Result(ResultConstants.SQLPREPARE);
            resultOut.setMainString(sql);
            resultOut.setMaxRows(1000);

            Result resultIn = sessionProxy.execute(resultOut);
            Assert.IsNotNull(resultIn, resultIn.getMainString());
            Assert.IsFalse(resultIn.isError(), resultIn.getMainString());
            Assert.AreEqual(resultIn.getSize(), 3, resultIn.getMainString());

            Iterator it = resultIn.iterator();

            object[] row = (object[])it.next();
            int statementID = ((Result)row[0]).getStatementID();

            row = (object[])it.next();
            Result rsmdDescriptor = (Result)row[0];

            row = (object[])it.next();
            Result pmdDescriptor = (Result)row[0];
            int[] parameterTypes = pmdDescriptor.metaData.getParameterTypes();

            resultOut = new Result(ResultConstants.SQLEXECUTE, parameterTypes,
                               statementID);
            resultOut.setMaxRows(1000);
            resultOut.setParameterData(parameters);

            resultIn = sessionProxy.execute(resultOut);
            Assert.IsNotNull(resultIn, resultIn.getMainString());
            Assert.IsFalse(resultIn.isError(), resultIn.getMainString());


            return resultIn;
        }

        public static Result GetPrepareStatement(SessionInterface sessionProxy, string sql)
        {
            Result resultOut = new Result(ResultConstants.SQLPREPARE);
            resultOut.setMainString(sql);
            resultOut.setMaxRows(1000);

            Result resultIn = sessionProxy.execute(resultOut);
            Assert.IsNotNull(resultIn, resultIn.getMainString());
            Assert.IsFalse(resultIn.isError(), resultIn.getMainString());
            Assert.AreEqual(resultIn.getSize(), 3, resultIn.getMainString());

            Iterator it = resultIn.iterator();

            object[] row = (object[])it.next();
            int statementID = ((Result)row[0]).getStatementID();

            row = (object[])it.next();
            Result rsmdDescriptor = (Result)row[0];

            row = (object[])it.next();
            Result pmdDescriptor = (Result)row[0];
            int[] parameterTypes = pmdDescriptor.metaData.getParameterTypes();

            resultOut = new Result(ResultConstants.SQLEXECUTE, parameterTypes,
                               statementID);
            resultOut.setMaxRows(1000);

            return resultOut;
        }

        public static Result ExecuteGetPrepareStatement(SessionInterface sessionProxy, Result resultOut, object[] parameters)
        {            
            resultOut.setParameterData(parameters);

            Result resultIn = sessionProxy.execute(resultOut);
            Assert.IsNotNull(resultIn, resultIn.getMainString());
            Assert.IsFalse(resultIn.isError(), resultIn.getMainString());

            return resultIn;
        }

        public static Result ExecuteUpdateSQL_Failure(SessionInterface sessionProxy, string sql)
        {
            Result resultOut = new Result(ResultConstants.SQLEXECDIRECT);
            resultOut.setMainString(sql);
            resultOut.setMaxRows(1000);

            Result resultIn = sessionProxy.execute(resultOut);
            Assert.IsNotNull(resultIn, resultIn.getMainString());
            Assert.IsTrue(resultIn.isError(), resultIn.getMainString());
            Assert.IsFalse(resultIn.isData(), resultIn.getMainString());

            return resultIn;
        }


        public static Result ExecuteSelectSQL(SessionInterface sessionProxy, string sql,int? count)
        {
            Result resultOut = new Result(ResultConstants.SQLEXECDIRECT);
            resultOut.setMainString(sql);
            resultOut.setMaxRows(1000);

            Result resultIn = sessionProxy.execute(resultOut);

            Assert.IsNotNull(resultIn, resultIn.getMainString());
            Assert.IsFalse(resultIn.isError(), resultIn.getMainString());
            Assert.IsTrue(resultIn.isData(), resultIn.getMainString());
            if(count != null)
                Assert.AreEqual(count, resultIn.getSize(), resultIn.getMainString());

            return resultIn;
        }

        public static void ExecuteSelectSQL_Failure(SessionInterface sessionProxy, string sql)
        {
            Result resultOut = new Result(ResultConstants.SQLEXECDIRECT);
            resultOut.setMainString(sql);
            resultOut.setMaxRows(1000);

            Result resultIn = sessionProxy.execute(resultOut);

            Assert.IsNotNull(resultIn, resultIn.getMainString());
            Assert.IsTrue(resultIn.isError(), resultIn.getMainString());
        
        }

        public static string CreateStdSelect(string table, int colCount)
        {
            string sql = "SELECT ";
            for (int i = 0; i < colCount; i++)
            {
                sql += "col" + (i+1);
                if (i != colCount - 1)
                    sql += " , ";
            }


            return sql + " FROM " + table+ " ; ";
        }

        public static string CreateStdInsert(string table, int colCount, params object[] vals)
        {
            string sql = "INSERT INTO " + table + " (";
            for (int i = 0; i < colCount; i++)
            {
                sql += "col" + (i + 1);
                if (i != colCount - 1)
                    sql += " , ";
            }

            sql += " ) VALUES ( ";

            for (int i = 0; i < colCount; i++)
            {
                if (vals[i] == null)
                {
                    sql += " NULL ";
                }
                else if(vals[i] is DateTime)
                    sql += "'"+ ((DateTime)vals[i]).ToString("o");
                else if (vals[i] is String)
                    sql += "'" + vals[i];
                else
                    sql += vals[i];

                if (vals[i] is String || vals[i] is DateTime)
                    sql += "'";
                if (i != colCount - 1)
                    sql += " , ";
            }

            return sql + " ); ";
        }



        public static string CreateStdUpdate(string table, string colName, object colVal)
        {
            string sql = "UPDATE " + table + " SET ";

            sql += colName + " = ";

            if (colVal is DateTime)
                sql += "'" + ((DateTime)colVal).ToString("o");
            else if (colVal is String)
                    sql += "'" + colVal;
                else
                    sql += colVal;
            if (colVal is String || colVal is DateTime)
                    sql += "'";       
         
            return sql + " ; ";
        }



        public static void MatchSingleResult(Result resultIn, params object[] vals)
        {
            //Type rtype;
            Iterator it = resultIn.iterator();
            object[] row = (object[])it.next();
            for (int j = 0; j < vals.Length; j++)            
            {        
                if( (vals[j]) is DateTime)
                    Assert.IsTrue((vals[j]).Equals(row[j]));
                else
                    Assert.AreEqual(vals[j],  row[j]);         
            }
        }



        public static void MatchSingleResultRow2(Result resultIn, int rowNumber, params object[] vals)
        {
            //Type rtype;
            Iterator it = resultIn.iterator();

            object[] row = (object[])it.next();
            for (int z = 0; z < rowNumber; z++)
                row = (object[])it.next();

            for (int j = 0; j < vals.Length; j++)
            {
                //rtype = (vals[j]).GetType();
                if ((vals[j]) is DateTime)
                    Assert.IsTrue((vals[j]).Equals(row[j]));
                else
                    Assert.AreEqual(Convert.ChangeType(vals[j], (row[j]).GetType()), row[j]);
            }
        }

        public static void MatchSingleResults(Result resultIn1, Result resultIn2, int colCount)
        {
            //Type rtype;
            Iterator it1 = resultIn1.iterator();
            Iterator it2 = resultIn2.iterator();

            while (it1.hasNext() && it2.hasNext())
            {
                object[] row1 = (object[])it1.next();
                object[] row2 = (object[])it2.next();

                for (int j = 0; j < colCount; j++)
                {
                    //rtype = (vals[j]).GetType();
                    if ((row1[j]) is DateTime)
                        Assert.IsTrue((row1[j]).Equals(row2[j]));
                    else
                        Assert.AreEqual(row1[j], row2[j]);
                }
            }          
        }




        public static void MatchSingleResultRow(Result resultIn, int rowNumber, params object[] vals)
        {
            //Type rtype;
            Iterator it = resultIn.iterator();

            object[] row = (object[])it.next();
            for (int z=0; z<rowNumber; z++)
                row = (object[])it.next();

            for (int j = 0; j < vals.Length; j++)
            {
                //rtype = (vals[j]).GetType();
                if ((vals[j]) is DateTime)
                    Assert.IsTrue((vals[j]).Equals(row[j]));
                else
                    Assert.AreEqual(vals[j], row[j]);
            }
        }



        public static void MatchMultiResult(Result resultIn,object[,] vals)
        {
            Iterator it = resultIn.iterator();
            //object[] row = null;
            int i = 0;
            foreach (var row in resultIn)
            {               
                //row = (object[])it.next();
                for (int j = 0; j < resultIn.getColumnCount(); j++)
                {
                    //rtype = (vals[j]).GetType();
                    if ((row[j]) is DateTime)
                        Assert.IsTrue((row[j]).Equals(vals[i,j]));
                    else                 
                        Assert.AreEqual(vals[i,j], row[j]);
                }

                i++;
            }
        }

    }
}
